home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1998 May: Tool Chest / Dev.CD May 98 TC.toast / Tool Chest / Testing & Debugging / Mac OS Development Toolkit / Automation Essentials 2.3.0 / Host Automation Folder / VU External Tool libs / Arbitrator.vu < prev    next >
Encoding:
Text File  |  1998-03-19  |  19.9 KB  |  528 lines  |  [TEXT/MPS ]

  1. #/******************* This is a full line in MPW printing on an 8.5 x 11, in Courier 9 ******************/
  2. #########################################################################
  3. #########################################################################
  4. ##                     Copyright Apple Computer, Inc. 1992-1997
  5. ##                                All rights reserved
  6. #########################################################################
  7. #########################################################################
  8. #    
  9. #    Library:        Arbitrator.vu
  10. #    
  11. #    Version:        2.1.1
  12. #    Description:
  13. #        This script provides arbitration and other services for scripts using the Launchquit 
  14. #        Engine (see LaunchQuit.lib) running on the same host. Due to limitations of VU, inter-host
  15. #        communications can not occur without an external tool. Hopefully someone will write such a 
  16. #        tool but for now, one host is the entire universe.
  17. #        
  18. #        The most important task of the Arbitrator is to prevent two targets from launching the same
  19. #        application at the same time. This is necessary if the application checks for serial number 
  20. #        conflicts over the network, which is a very nasty habit, discouraged by Apple and disparaged
  21. #        by network managers everywhere. However, it is a fact of life that some applications not only
  22. #        refuse to run under such a circumstance, they actually undo their serial number registration. 
  23. #        All subsequent launches fail because the script does not anticipate the registration dialog.
  24. #        
  25. #        Another task is to store how many test cases a script has completed. If the script stops 
  26. #        unexpectedly, the user can simply restart the script without having to comment out the 
  27. #        completed test cases. On startup, the script checks with the Arbitrator to see if it  
  28. #        completed the last run and determines where it should resume.
  29. #        
  30. #        These are the status variables maintained by the script:
  31. #        myActors    :=    { [ 'actorName' [, … ] };
  32. #        appsInUse    :=     { [{application1, actorName}][, {application2, actorName}]… }
  33. #        resumees    :=     { [{ actor1, lastTestCase1}][, {actor2, lastTestCase2}]… }
  34. #    Contains:
  35. #        PrepareArbitrator()
  36. #        UsingArbitrator()
  37. #        ReleaseArbitrator()
  38. #        AcquireID()
  39. #        ReleaseID()
  40. #    
  41. #    History:
  42. #        Date:        By:        Changes:
  43. #        12/15/92    SBR        Created
  44. #        09/29/94    SBR        Changed to use Arbitrator external tool
  45. #        07/21/95    SBR        Added AutoDestruct feature  
  46. #        01/30/97    SBR        Deleted older exception code and comments.
  47. #
  48. #    Version      Date        By    Comment
  49. #    =======    ========    ===    =======
  50. #    1.0.0    02/12/97    JAS    Added 'vers' resources to library.
  51. #                            These should always match tool version when tool is revved.
  52. #    
  53. #########################################################################
  54. #########################################################################
  55.  
  56. Libraries 
  57.     "Report.lib";
  58.  
  59.  
  60. tool Arbitrator s:'Arbi'
  61. begin
  62.     # Services specific to Arbitrator:
  63.     
  64.     # To lock an ID (a list containing one or more values, each value can be a 
  65.     # Boolean, string, integer, or list type) 
  66.     Service    "LockID"( 'list', 'symbol', 'undefined' ) return 'symbol';
  67.  
  68.     # first parameter is the ID (a list) to lock as a resource acquisition 
  69.     # second parameter is Boolean: true means lock, false means unlock 
  70.     # third parameter is the autodestruct 'integer' (used for locking only)
  71.     # return value is Boolean, true means success, false means failure
  72.     
  73.  
  74.     # To set up an autodestruct ID 
  75.     Service    "AutoDestruct"( ) return 'symbol';
  76.  
  77.     # call this once per script asynchronously and provide the job ID when you lock names
  78.     # when a script exits, the names it locked will be unlocked automatically
  79.     # return value is Boolean, true means success, false means failure
  80.     
  81.  
  82.     # To dump all locked IDs 
  83.     Service    "DumpIDs"( ) return 'list';
  84.  
  85.     # call this for debugging the Arbitrator LockID service
  86.     # return value is the list of locked IDs
  87.  
  88. end;
  89.  
  90. #########################################################################
  91. #    task            PrepareArbitrator(v_level)
  92. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  93. #    Description:    Ensures the Arbitrator is ready to receive a request. Use this 
  94. #                    routine so in the future if the Arbitrator becomes an External Tool
  95. #                    or anything else but a script, we do not use openSession(). 
  96. #                    
  97. #                    NOTE: The hidden global gArbitratorIsPrepared can have two values:
  98. #                    undefined or an integer. Undefined indicates the Arbitrator is in
  99. #                    the released (unknown) state. A call to this task with the global 
  100. #                    containing undefined will cause the task to try preparing the 
  101. #                    Arbitrator, and the global will be assigned the integer value of 
  102. #                    the asynchronous job ID from the AutoDestruct service. All
  103. #                    subsequent calls to this task will just return the value of 
  104. #                    gArbitratorIsPrepared. To reset the value of this hidden global
  105. #                    to undefined, call ReleaseArbitrator().
  106. #                    
  107. #    Parameters:        v_level: verbosity level for reporting
  108. #    Returns:        true if successful, false if not
  109. #    Examples:        PrepareArbitrator();
  110. #    Assumptions:    VU 2.0.1
  111. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  112. #    History:
  113. #        01/14/94    SBR        Created
  114. #        09/29/94    SBR        Changed to use Arbitrator external tool
  115. #########################################################################
  116. task    PrepareArbitrator(v_level := 1)
  117. begin
  118.     global gArbitratorIsPrepared;
  119.     
  120.     if isUndefined(gArbitratorIsPrepared)            # First time through, make a
  121.     begin                                            # new session, wait if needed
  122.         theResult := Arbitrator('initialize');
  123.         if theResult[1]
  124.         begin
  125.             RIncomplete("PrepareArbitrator initialize: {theResult}",v_level);
  126.         end;
  127.         else
  128.         begin
  129.             theResult := Arbitrator('AutoDestruct') async:true;
  130.             if theResult[1] = 1                                # normal asynchronous result
  131.             begin
  132.                 gArbitratorIsPrepared := theResult[2];        # store job ID for AutoDestruct
  133.             end;
  134.             else
  135.             begin
  136.                 RIncomplete("PrepareArbitrator AutoDestruct: {theResult}",v_level);
  137.                 gArbitratorIsPrepared := undefined;
  138.             end;
  139.         end;
  140.     end;
  141. #        else if gArbitratorIsPrepared                    # just check old session
  142. #        begin
  143. #            theResult := Arbitrator('initialize');
  144. #            if theResult[1]
  145. #            begin
  146. #                RIncomplete("PrepareArbitrator re-initialize: {theResult}",v_level);
  147. #                RStatus("The Arbitrator disappeared after it was prepared!",v_level);
  148. #                gArbitratorIsPrepared := undefined;
  149. #            end;
  150. #        end;
  151.  
  152.     return gArbitratorIsPrepared;
  153. end;
  154.  
  155.  
  156. #########################################################################
  157. #    task            UsingArbitrator(v_level)
  158. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  159. #    Description:    Verifies the Arbitrator is supposed to be ready to receive a request.
  160. #                    Just returns the value of the global gArbitratorIsPrepared. Will not 
  161. #                    prepare the Arbitrator if it is not ready. 
  162. #    Parameters:        v_level: verbosity level for reporting
  163. #    Returns:        true if global is true, false if not
  164. #    Examples:        needToRegister := UsingArbitrator();
  165. #    Assumptions:    VU 2.0.1
  166. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  167. #    History:
  168. #        01/14/94    SBR        Created
  169. #########################################################################
  170. task    UsingArbitrator(v_level := 5)
  171. begin
  172.     global gArbitratorIsPrepared;
  173.     
  174.     if isUndefined(gArbitratorIsPrepared)
  175.     begin
  176.         return false;
  177.     end;
  178.     else 
  179.         return gArbitratorIsPrepared;
  180. end;
  181.  
  182.  
  183. #########################################################################
  184. #    task            ReleaseArbitrator(v_level)
  185. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  186. #    Description:    Releases the Arbitrator from the session created by PrepareArbitrator().
  187. #                    In the future this may quit the External Tool, but for now we 
  188. #                    assume other scripts are also using the tool, so do not quit.
  189. #    Parameters:        v_level: verbosity level for reporting
  190. #    Returns:        nothing
  191. #    Examples:        ReleaseArbitrator();
  192. #    Assumptions:    VU 2.0.1
  193. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  194. #    History:
  195. #        01/14/94    SBR        Created
  196. #        09/29/94    SBR        Changed to use Arbitrator external tool
  197. #########################################################################
  198. task    ReleaseArbitrator(v_level := 5)
  199. begin
  200.     global gArbitratorIsPrepared;
  201.  
  202.     if not gArbitratorIsPrepared
  203.         RIncomplete("ReleaseArbitrator: Arbitrator is not prepared, can not release.",1);
  204.     
  205.     gArbitratorIsPrepared := undefined;
  206. end;
  207.  
  208.  
  209. #########################################################################
  210. #    task            AcquireID( pID, v_level )
  211. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  212. #    Description:    Uses the Arbitrator to reserve a resource for exclusive use.
  213. #                    See the Arbitrator Script for more explanations.
  214. #    Parameters:        pID:        The ID (a list) to lock. It must be non-empty, but it 
  215. #                                may contain Boolean, string, integer, and list types.
  216. #                    v_level:     verbosity level for reporting
  217. #    Returns:        true if successful, false if not
  218. #    Examples:        AcquireID( {'application','4th Dimension 2.2.3@'} )
  219. #                    AcquireID( {'host folder','full:path:name',42} )
  220. #    Assumptions:    VU 2.1
  221. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  222. #    History:
  223. #        02/18/95    SBR        created
  224. #########################################################################
  225. task    AcquireID( pID, v_level := 2 )
  226. begin
  227.     tAutoDestructCode := PrepareArbitrator();
  228.     if isUndefined(tAutoDestructCode)
  229.         return false;
  230.     
  231.     arbResponse := Arbitrator( 'LockID', pID, true, tAutoDestructCode );
  232.     
  233.     if arbResponse[1]             # an error occurred
  234.     begin
  235.         return RIncomplete("Arbitrator LockID: a tool error occurred: {arbResponse}.",v_level);
  236.     end;
  237.     
  238.     if arbResponse[2]             # no error occurred, acquire succeeded
  239.     begin
  240.         tIDIsLocked := true;
  241.     end;
  242.     else                          # no error occurred, acquire failed
  243.     begin
  244.         arbWaitTime := 60;
  245.         RStatus("Waiting {arbWaitTime} seconds for ID {pID} to be unlocked.",v_level);
  246.         wait(arbWaitTime);
  247.     end;
  248.     return tIDIsLocked;
  249. end;
  250.  
  251.  
  252. #########################################################################
  253. #    task            ReleaseID( pID, v_level )
  254. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  255. #    Description:    Uses the Arbitrator to unlock a resource so others can use it.
  256. #                    See the Arbitrator Script for more explanations.
  257. #    Parameters:        pID:        The ID (a list) to unlock.
  258. #                    v_level:     verbosity level for reporting
  259. #    Returns:        true if successful, false if not
  260. #    Examples:        ReleaseID( {'application','4th Dimension 2.2.3@'} )
  261. #    Assumptions:    VU 2.1
  262. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  263. #    History:
  264. #        02/18/95    SBR        created
  265. #########################################################################
  266. task    ReleaseID( pID, v_level := 2 )
  267. begin
  268.     if not PrepareArbitrator()
  269.         return false;
  270.     
  271.     arbResponse := Arbitrator( 'LockID', pID, false );
  272.     
  273.     if arbResponse[1]             # an error occurred
  274.     begin
  275.         return RIncomplete("ReleaseID: Arbitrator tool error occurred: {arbResponse}.",v_level);
  276.     end;
  277.     
  278.     if arbResponse[2]             # no error occurred, release succeeded
  279.     begin
  280.         return true;
  281.     end;
  282.     else                          # no error occurred, release failed
  283.     begin
  284.         return false;
  285.     end;
  286. end;
  287.  
  288.  
  289. #########################################################################
  290. #    script            Arbitrator( Verbosity_Level := 2, Quick_Waits := false )
  291. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  292. #    Description:    The script which provides the Arbitrator services. It is a large
  293. #                    loop, which looks for actors not yet connected and tries to open a  
  294. #                    VU message session with each of them. Once connected, it loops waiting 
  295. #                    for messages from each one. When it receives a message it responds
  296. #                    immediately depending on the contents.
  297. #                    
  298. #                    After every iteration of the loop, the script waits for a short time
  299. #                    to allow other scripts to execute. This idleTime is autmatically
  300. #                    adjusted based on the level of activity. If there are no messages 
  301. #                    from any actors, the idleTime is slightly increased until it 
  302. #                    reaches 15 seconds, which is the longest reasonable time to wait. 
  303. #                    If there are any messages from other actors during an iteration, the 
  304. #                    idleTime is slightly reduced until it reaches a minimum of 2 seconds.
  305. #                    
  306. #                    If you want to keep the idleTime low for experimenting and bypass
  307. #                    the automatic adjustment, use the Quick_Waits script parameter.
  308. #    Parameters:        Verbosity_Level: set global verbosity level for reporting
  309. #                    Quick_Waits:    Boolean true:    idleTime = 2 seconds
  310. #                                    Boolean false:    adjust idleTime automatically
  311. #                                    integer  > 0:    idleTime = Quick_Waits seconds
  312. #                                    integer  = 0:    adjust idleTime automatically
  313. #    Returns:        true if successful, false if not
  314. #    Examples:        PrepareArbitrator();
  315. #    Assumptions:    VU 2.0.1
  316. #∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞∞
  317. #    History:
  318. #        12/15/92    SBR        Created
  319. #        01/14/94    SBR        Added auxilliary tasks
  320. #        02/02/94    SBR        Formatted to our script standards, added comments,
  321. #                            improved Quick_Waits parameter behavior.
  322. #        02/02/94    SBR        Changed timeout from 0 to 120 seconds for receiving the 
  323. #                            subsequent messages in a list, e.g. this makes a 
  324. #                            registration request atomic. This is to try and fix the
  325. #                            synchronization problems with multiple scripts.
  326. #########################################################################
  327. #    script Arbitrator ( Verbosity_Level := 2, Quick_Waits := false )
  328. #    begin
  329. #        appsInUse := {};
  330. #        myActors := {};
  331. #        resumees := {};
  332. #        
  333. #        rPushVerbosity(Verbosity_Level);
  334. #        idleTime := 10;
  335. #        
  336. #        # check if Arbitrator is already running in another place, exit if true
  337. #        actorName(" Arbitrator");            #set for easy NoteBook/Script Parameter window selection
  338. #        if match [actor t:"Arbitrator"]! 
  339. #        begin
  340. #            RStatus("Another actor is already running the Arbitrator script on this host.", 1);
  341. #            exit;
  342. #        end;
  343. #        else begin
  344. #            actorName("Arbitrator");
  345. #            RStatus("This actor is now the Arbitrator for this host.", 1);
  346. #        end;
  347. #            
  348. #        while true             # the main loop in the script
  349. #        begin
  350. #            # get list of actors who are not registered; remove the Arbitrator
  351. #            match [actor t:$allActors];
  352. #            
  353. #            allActors := remove(isMember('Arbitrator', allActors), allActors);
  354. #            newActors := {};
  355. #            
  356. #            for each thisActor in allActors
  357. #                if not isMember(thisActor, myActors)
  358. #                    newActors := newActors + {thisActor};
  359. #            if newActors 
  360. #                #println "∂nnewActors = ",newActors;
  361. #            
  362. #            # if any have not opened a session with Arbitrator try an openSession
  363. #            for each newActor in newActors 
  364. #            begin
  365. #                if connect_to(newActor, 0)         # do not wait, just create an outstanding request
  366. #                begin
  367. #                    myActors := myActors + {newActor};
  368. #                    resumeValue := assoc(newActor, resumees);
  369. #                    if isUndefined(resumeValue) 
  370. #                    begin
  371. #                        resumees := resumees + {{newActor,0}};
  372. #                        resumeValue := 0;
  373. #                    end;
  374. #                    println "∂nopenSession with {newActor}";
  375. #                end;
  376. #            end;
  377. #            
  378. #            # check for service requests and do them
  379. #            for each thisActor in myActors 
  380. #            begin
  381. #                #println "Checking actor: {thisActor} after waiting {idleTime}";
  382. #                myMessage := false;
  383. #                if not match [actor t:thisActor]!             #actor aborted: remove it and it's apps
  384. #                begin
  385. #                    println "ACTOR {thisActor} SUDDENLY DISAPPEARED!";
  386. #                    myMessage := 'deleteActor';
  387. #                end;
  388. #                
  389. #                if not myMessage            #i.e. myMessage is not 'deleteActor'
  390. #                    myMessage := receive_list(thisActor, 1, 0)[1];
  391. #                    
  392. #                if myMessage
  393. #                begin
  394. #                    println ' ';
  395. #                    if myMessage = 'beginTC'
  396. #                    begin
  397. #                        theTestCase := receive_list(thisActor, 1, 120)[1];     # wait for 2nd string 
  398. #                        if theTestCase
  399. #                        begin
  400. #                            println "{thisActor} began test case: '", theTestCase, "'; no response needed.";
  401. #                            resumees := replace({thisActor, theTestCase},
  402. #                                isMember({thisActor, assoc(thisActor,resumees)}, resumees), resumees);
  403. #                        end;
  404. #                    end;
  405. #                    
  406. #                    else if myMessage ~= /resume≈/
  407. #                    begin
  408. #                        println "{thisActor} requested '{myMessage}'"; 
  409. #                        resumeValue := assoc(thisActor, resumees);
  410. #                        println "resumees: ",resumees;
  411. #                        println "resumeValue: ",resumeValue;
  412. #                        if resumeValue = 0 begin
  413. #                            myMessage := 'resumeReset';
  414. #                        end;
  415. #                        else returnMessage := {thisActor, resumeValue};
  416. #                        if (myMessage = 'resumeReset')
  417. #                        begin
  418. #                            if not (resumeValue = 0)
  419. #                                resumees := replace({thisActor, 0}, isMember({thisActor, resumeValue}, 
  420. #                                    resumees), resumees);
  421. #                            returnMessage := {thisActor,'resumeReset'};
  422. #                        end;
  423. #                        send_list(thisActor, returnMessage);
  424. #                    end;
  425. #                    
  426. #                    else if myMessage = 'useApplication'
  427. #                    begin
  428. #                        theAppToUse := receive_list(thisActor, 1, 120)[1];     # wait for 2nd string 
  429. #                        if theAppToUse
  430. #                        begin
  431. #                            println "{thisActor} requested 'useApplication {theAppToUse}'"; 
  432. #                            println "appsInUse before registering app: {appsInUse}"; 
  433. #                            appUser := assoc(theAppToUse, appsInUse);
  434. #                            if not appUser
  435. #                            begin
  436. #                                appsInUse := appsInUse + {{theAppToUse, thisActor}};
  437. #                                println "appsInUse after registering app: {appsInUse}"; 
  438. #                                println "myActors after registering app: {myActors}"; 
  439. #                                send_list(thisActor, {thisActor, 'useApplication', theAppToUse});
  440. #                                println "gave {thisActor} permission to 'useApplication {theAppToUse}'"; 
  441. #                            end;
  442. #                            else begin
  443. #                                send_list(thisActor, {thisActor, "it is in use by {appUser}", theAppToUse});
  444. #                                println "Denied {thisActor} permission to 'useApplication {theAppToUse}'";
  445. #                            end;
  446. #                        end;
  447. #                    end;
  448. #                    
  449. #                    else if myMessage = 'quitApplication'
  450. #                    begin
  451. #                        theAppToQuit := receive_list(thisActor, 1, 120)[1];     # wait for 2nd string 
  452. #                        if theAppToQuit
  453. #                        begin
  454. #                            println "{thisActor} requested 'quitApplication {theAppToQuit}'"; 
  455. #                            println "appsInUse before quitting app: {appsInUse}"; 
  456. #                            appUser := assoc(theAppToQuit, appsInUse);
  457. #                            
  458. #                            if not appUser                         #give permission anyway if not registered
  459. #                            begin
  460. #                                send_list(thisActor, {theActor, 'quitApplication', theAppToQuit});
  461. #                                println "'{theAppToQuit}' is not registered to 'useApplication {theAppToQuit}'"; 
  462. #                                println "gave {thisActor} permission to 'quitApplication {theAppToQuit}'"; 
  463. #                            end;
  464. #                            else if appUser = thisActor         #delete the app registration
  465. #                            begin
  466. #                                appsInUse := remove(isMember({theAppToQuit, appUser}, appsInUse), appsInUse);
  467. #                                println "appsInUse after quitting app: {appsInUse}"; 
  468. #                                send_list(thisActor, {thisActor, 'quitApplication', theAppToQuit});                            
  469. #                                println "gave {thisActor} permission to 'quitApplication {theAppToQuit}'"; 
  470. #                            end;
  471. #                            else begin
  472. #                                send_list(thisActor, {thisActor, 
  473. #                                    "'{theAppToQuit}' registered for use by {appUser}", theAppToQuit});
  474. #                                println "denied {thisActor} permission to 'quitApplication {theAppToQuit}'"; 
  475. #                            end;
  476. #                        end;
  477. #                    end;
  478. #    
  479. #                    else if myMessage = 'disconnect'
  480. #                    begin
  481. #                        println "{thisActor} requested 'disconnect'"; 
  482. #                        send_list(thisActor, {thisActor, 'disconnect'});
  483. #                        myMessage := 'deleteActor';
  484. #                    end;
  485. #                    
  486. #                    if myMessage = 'deleteActor'
  487. #                    begin
  488. #                        println "Arbitrator requested 'deleteActor {thisActor}'"; 
  489. #                        index := 1;
  490. #                        for i := 1 to card appsInUse
  491. #                        begin
  492. #                            if appsInUse[index][2] = thisActor
  493. #                                appsInUse := remove(index, appsInUse);
  494. #                            else index := index + 1;
  495. #                        end;
  496. #                        println "appsInUse after un-registering {thisActor}'s apps: {appsInUse}";
  497. #                        myActors := remove(isMember(thisActor, myActors), myActors);
  498. #                        println "myActors after un-registering {thisActor}: {myActors}";
  499. #                        temp := assoc(thisActor,resumees);
  500. #                        if temp
  501. #                            println "actor {thisActor} will resume at {temp}";
  502. #                        disconnect_from(thisActor);
  503. #                    end;
  504. #                    
  505. #                    if idleTime > 10
  506. #                        idleTime := 10;                #shorten wait when busy
  507. #                    else if idleTime >= 2
  508. #                        idleTime := idleTime - 2;
  509. #                end;    #if myMessage
  510. #                else if idleTime <= 13
  511. #                    idleTime := idleTime + 2;        #lengthen wait when idle, max 15 sec
  512. #                
  513. #                if Quick_Waits
  514. #                begin
  515. #                    if typeOf(Quick_Waits) = 'Boolean'
  516. #                        idleTime := 2;
  517. #                    else if typeOf(Quick_Waits) = 'integer'
  518. #                        idleTime := Quick_Waits;
  519. #                end;
  520. #                        
  521. #                wait(idleTime);                        # give the other scripts time
  522. #            end;        #for each thisActor in myActors
  523. #            
  524. #        end;
  525. #    end;
  526.  
  527.  
  528.